package org.dftproject.genesis.ui.widgets.gallery;

import org.dftproject.genesis.ui.figures.ButtonPainter;
import org.dftproject.genesis.ui.figures.TooltipLabel;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Cursors;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ImageFigure;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.MouseMotionListener;
import org.eclipse.draw2d.StackLayout;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;

public class GalleryButtonFigure extends Figure {

	public static final Color backgroundColor = ColorConstants.listBackground;
	public static final Color borderColor = new Color(null, 128, 128, 128);

	private static final int margin = 6;

	private boolean hover;
	private final boolean selected;
	private final Runnable runnable;

	public GalleryButtonFigure(Image image, boolean selected, String tooltipText, Runnable runnable) {
		this(new ImageFigure(image), selected, tooltipText, runnable);
	}
	
	public GalleryButtonFigure(IFigure figure, boolean selected, String tooltipText, Runnable runnable) {
		this.selected = selected;
		this.runnable = runnable;

		setCursor(Cursors.HAND);
		setRequestFocusEnabled(true);
		addListeners();

		setLayoutManager(new StackLayout());
		setBorder(new MarginBorder(margin));
		setPreferredSize(new Dimension(64 + margin, 64 + margin));
		
		setToolTip(new TooltipLabel(tooltipText));

		this.add(figure);
	}

	protected void addListeners() {
		MouseTracker tracker = new MouseTracker();
		addMouseMotionListener(tracker);
		addMouseListener(tracker);
	}

	protected boolean getHover() {
		return hover;
	}

	protected void setHover(boolean hover) {
		this.hover = hover;
	}

	protected void setPressed(boolean pressed) {
		if (pressed)
			setBorder(new MarginBorder(margin + 1, margin + 1, margin - 1, margin - 1));
		else
			setBorder(new MarginBorder(margin));
	}

	@Override
	public void paint(Graphics graphics) {
		int state = ButtonPainter.NONE;
		if (hover)
			state |= ButtonPainter.HOVER;
		if (selected)
			state |= ButtonPainter.SELECTED;
		Rectangle bounds = getBounds();
		
		ButtonPainter painter = new ButtonPainter();
		painter.drawButton(graphics, state, bounds);

		graphics.pushState();
		graphics.setAntialias(SWT.ON);
		super.paint(graphics);
		graphics.popState();
	}

	protected class MouseTracker extends MouseMotionListener.Stub implements MouseListener {

		private boolean mouseDown;

		public void mousePressed(MouseEvent me) {
			requestFocus();
			me.consume();

			mouseDown = true;
			setPressed(true);
		}

		public void mouseReleased(MouseEvent me) {
			mouseDown = false;

			if (getBounds().contains(me.getLocation())) {
				if (runnable != null)
					runnable.run();
			}

			setPressed(false);
		}

		public void mouseDoubleClicked(MouseEvent me) {
		}

		@Override
		public void mouseEntered(MouseEvent me) {
			setHover(true);
			repaint();
		}

		@Override
		public void mouseExited(MouseEvent me) {
			setHover(false);
			repaint();
		}

		@Override
		public void mouseDragged(MouseEvent me) {
			boolean mouseOver = getBounds().contains(me.getLocation());
			if (mouseDown)
				setPressed(mouseOver);
			setHover(mouseOver);
			revalidate();
		}

	}

}
